package com.ChainBizPro.system.controller;

import com.ChainBizPro.system.annotation.AuthCheck;
import com.ChainBizPro.system.common.BaseResponse;
import com.ChainBizPro.system.common.DeleteRequest;
import com.ChainBizPro.system.common.ErrorCode;
import com.ChainBizPro.system.common.ResultUtils;
import com.ChainBizPro.system.constant.UserConstant;
import com.ChainBizPro.system.exception.BusinessException;
import com.ChainBizPro.system.exception.ThrowUtils;
import com.ChainBizPro.system.model.domain.PurchaseOrders;
import com.ChainBizPro.system.model.domain.User;
import com.ChainBizPro.system.model.dto.Order.OrderUpdateMyRequest;
import com.ChainBizPro.system.model.dto.Order.OrdersQueryRequest;
import com.ChainBizPro.system.model.dto.Order.PurchaseOrdersAddRequest;
import com.ChainBizPro.system.model.dto.Order.OrderPaymentQueryRequest;
import com.ChainBizPro.system.model.enums.PaymentStatusEnum;
import com.ChainBizPro.system.model.vo.PurchaseOrderVO;
import com.ChainBizPro.system.service.PurchaseOrdersService;
import com.ChainBizPro.system.service.SuppliersService;
import com.ChainBizPro.system.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 订单接口
 *
 * @author liusijia
 */
@RestController
@RequestMapping("/order")
@Api(tags = "订单接口")
@Slf4j
public class OrderController {

    @Resource
    private PurchaseOrdersService purchaseOrdersService;

    @Resource
    private UserService userService;

    // region 增删改查

    /**
     * 创建订单
     *
     * @param purchaseOrdersAddRequest
     * @param request
     * @return SupplierId
     */
    @PostMapping("/add")
    @ApiOperation(value = "创建订单")
    public BaseResponse<Long> addOrder(@RequestBody PurchaseOrdersAddRequest purchaseOrdersAddRequest,
            HttpServletRequest request) {
        if (purchaseOrdersAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        PurchaseOrders purchaseOrder = new PurchaseOrders();
        boolean result = purchaseOrdersService.addPurchaseOrders(purchaseOrdersAddRequest, request);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(purchaseOrder.getSupplierId());
    }

    /**
     * 删除订单
     *
     * @param deleteRequest
     * @return
     */
    @PostMapping("/delete")
    @ApiOperation(value = "删除订单")
    public BaseResponse<Boolean> deleteSupplier(@RequestBody DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = purchaseOrdersService.removeById(deleteRequest.getId());
        return ResultUtils.success(result);
    }

    /**
     * 更新订单
     *
     * @param orderUpdateRequest
     * @param request
     * @return
     */
    @PostMapping("/update")
    @ApiOperation(value = "更新订单")
    public BaseResponse<Boolean> updateOrder(@RequestBody OrderUpdateMyRequest orderUpdateRequest,
            HttpServletRequest request) {
        if (orderUpdateRequest == null || orderUpdateRequest.getOrderId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        if (orderUpdateRequest.getOrderId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数错误");
        }
        PurchaseOrders purchaseOrders = new PurchaseOrders();
        BeanUtils.copyProperties(orderUpdateRequest, purchaseOrders);
        boolean result = purchaseOrdersService.updateById(purchaseOrders);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(result);
    }

    /**
     * 审核订单（仅管理员）
     *
     * @param orderId
     * @param status
     * @return
     */
    @PostMapping("/check")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @ApiOperation(value = "审核订单（仅管理员）")
    public BaseResponse<PurchaseOrders> checkOrderById(long orderId, String status) {
        if (orderId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数错误");
        }
        PurchaseOrders purchaseOrders = purchaseOrdersService.getById(orderId);
        ThrowUtils.throwIf(purchaseOrders == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在");
        purchaseOrders.setStatus(status);
        return ResultUtils.success(purchaseOrders);
    }

    /**
     * 用户查询自己全部的订单
     *
     * @param request
     * @return
     */
    @PostMapping("/get/all/user")
    @ApiOperation(value = "用户查询自己全部的订单")
    public BaseResponse<Page<PurchaseOrderVO>> getSuppliersVOById(@RequestBody OrdersQueryRequest orderIdQueryRequest,
            HttpServletRequest request) {
        long current = orderIdQueryRequest.getCurrent() == 0 ? 1 : orderIdQueryRequest.getCurrent();
        long size = orderIdQueryRequest.getPageSize() == 0 ? 10 : orderIdQueryRequest.getPageSize();

        Long userId = userService.getLoginUser(request).getId();
        // 分页信息封装Page对象
        Page<PurchaseOrderVO> pageParam = new Page(current, size);
        Page<PurchaseOrderVO> queryWrapper = purchaseOrdersService.getQueryWrapperByUser(pageParam, orderIdQueryRequest,
                userId);
        return ResultUtils.success(queryWrapper);
    }

    /**
     * 分页获取全部用户订单（仅管理员）
     *
     * @param ordersQueryRequest
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @ApiOperation(value = "分页获取全部用户订单（仅管理员）")
    public BaseResponse<Page<PurchaseOrderVO>> listPurchaseOrdersByPage(
            @RequestBody OrdersQueryRequest ordersQueryRequest) {
        long current = ordersQueryRequest.getCurrent() == 0 ? 1 : ordersQueryRequest.getCurrent();
        long size = ordersQueryRequest.getPageSize() == 0 ? 10 : ordersQueryRequest.getPageSize();
        // 分页信息封装Page对象
        Page<PurchaseOrderVO> pageParam = new Page(current, size);
        Page<PurchaseOrderVO> queryWrapper = purchaseOrdersService.getQueryWrapperByAdmin(pageParam,
                ordersQueryRequest);
        return ResultUtils.success(queryWrapper);
    }
    // endregion

    /**
     * 更新个人的订单信息
     *
     * @param ordersQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/update/my")
    @ApiOperation(value = "更新个人的订单信息")
    public BaseResponse<Boolean> updateSupplier(@RequestBody OrderUpdateMyRequest ordersQueryRequest,
            HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "用户不存在");
        }
        QueryWrapper<PurchaseOrders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("orderId", ordersQueryRequest.getOrderId());
        PurchaseOrders purchaseOrder = purchaseOrdersService.getOne(queryWrapper);
        long userId = loginUser.getId();
        if (userId != purchaseOrder.getUserId()) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR, "只能修改自己的订单");
        }
        BeanUtils.copyProperties(ordersQueryRequest, purchaseOrder);
        boolean result = purchaseOrdersService.updateById(purchaseOrder);
        return ResultUtils.success(result);
    }

    /**
     * 支付订单
     */
    @PostMapping("/pay")
    @ApiOperation(value = "支付订单")
    public BaseResponse<Boolean> payOrder(@RequestParam Long orderId, HttpServletRequest request) {
        if (orderId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        PurchaseOrders order = purchaseOrdersService.getById(orderId);
        if (order == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单不存在");
        }

        // 校验订单状态
        if (!"unpaid".equals(order.getPaymentStatus())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "订单状态不正确");
        }

        // 更新订单状态
        order.setPaymentStatus("paid");
        order.setPaymentTime(new Date());
        // 支付成功后将订单状态改为已完成
        order.setStatus("completed");
        boolean result = purchaseOrdersService.updateById(order);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true, "订单支付成功");
    }

    /**
     * 申请退款
     */
    @PostMapping("/refund")
    @ApiOperation(value = "申请退款")
    public BaseResponse<Boolean> refundOrder(@RequestParam Long orderId, HttpServletRequest request) {
        if (orderId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        PurchaseOrders order = purchaseOrdersService.getById(orderId);
        if (order == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单不存在");
        }
        // 校验是否是自己的订单
        if (!order.getUserId().equals(loginUser.getId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权限");
        }
        // 校验订单状态
        if (!"paid".equals(order.getPaymentStatus())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "订单状态不正确");
        }

        // 更新订单状态
        order.setPaymentStatus("refunded");
        order.setRefundTime(new Date());
        // 退款成功后将订单状态改为已完成
        order.setStatus("completed");
        boolean result = purchaseOrdersService.updateById(order);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true, "退款申请成功");
    }

    /**
     * 获取订单支付状态
     *
     * @param orderId
     * @param request
     * @return
     */
    @GetMapping("/payment/status")
    @ApiOperation(value = "获取订单支付状态")
    public BaseResponse<String> getPaymentStatus(@RequestParam Long orderId, HttpServletRequest request) {
        if (orderId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        PurchaseOrders order = purchaseOrdersService.getById(orderId);
        if (order == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单不存在");
        }
        // 校验是否是自己的订单或管理员
        if (!order.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权限");
        }
        // 转换支付状态为中文
        String paymentStatus = PaymentStatusEnum.getValueByCode((String) order.getPaymentStatus());
        return ResultUtils.success("订单支付状态：" + paymentStatus);
    }

    /**
     * 查询已支付订单
     */
    @PostMapping("/list/paid")
    @ApiOperation(value = "查询已支付订单")
    public BaseResponse<Page<PurchaseOrderVO>> listPaidOrders(@RequestBody OrderPaymentQueryRequest queryRequest,
            HttpServletRequest request) {
        long current = queryRequest.getCurrent() == 0 ? 1 : queryRequest.getCurrent();
        long size = queryRequest.getPageSize() == 0 ? 10 : queryRequest.getPageSize();
        User loginUser = userService.getLoginUser(request);
        Page<PurchaseOrderVO> pageParam = new Page<>(current, size);
        Page<PurchaseOrderVO> orderPage = purchaseOrdersService.getOrdersByPaymentStatus(pageParam,
                "paid", queryRequest, loginUser.getId());
        return ResultUtils.success(orderPage);
    }

    /**
     * 查询未支付订单
     */
    @PostMapping("/list/unpaid")
    @ApiOperation(value = "查询未支付订单")
    public BaseResponse<Page<PurchaseOrderVO>> listUnpaidOrders(@RequestBody OrderPaymentQueryRequest queryRequest,
            HttpServletRequest request) {
        long current = queryRequest.getCurrent() == 0 ? 1 : queryRequest.getCurrent();
        long size = queryRequest.getPageSize() == 0 ? 10 : queryRequest.getPageSize();
        User loginUser = userService.getLoginUser(request);
        Page<PurchaseOrderVO> pageParam = new Page<>(current, size);
        Page<PurchaseOrderVO> orderPage = purchaseOrdersService.getOrdersByPaymentStatus(pageParam,
                "unpaid", queryRequest, loginUser.getId());
        return ResultUtils.success(orderPage);
    }

    /**
     * 取消订单
     *
     * @param orderId
     * @param request
     * @return
     */
    @PostMapping("/cancel")
    @ApiOperation(value = "取消订单")
    public BaseResponse<Boolean> cancelOrder(@RequestParam Long orderId, HttpServletRequest request) {
        if (orderId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        User loginUser = userService.getLoginUser(request);
        PurchaseOrders order = purchaseOrdersService.getById(orderId);
        if (order == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单不存在");
        }
        
        // 校验是否是自己的订单
        if (!order.getUserId().equals(loginUser.getId())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权限");
        }
        
        // 校验订单状态
        if ("cancelled".equals(order.getStatus())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "订单已取消");
        }
        
        if ("paid".equals(order.getPaymentStatus())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "已支付的订单不能取消");
        }

        // 更新订单状态
        order.setStatus("cancelled");
        boolean result = purchaseOrdersService.updateById(order);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true, "订单取消成功");
    }

}
